package com.maslyk.invitation.service.email;

import java.util.Collection;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;

import com.maslyk.configuration.ConfigurationManager;
import com.maslyk.invitation.exception.LogicalException;
import com.maslyk.invitation.exception.SystemException;

public class MessagingEmailService
{
    private static final String MESSAGE_CONTENT_TYPE_HTML = "text/html; charset=UTF-8";
    private Properties properties = null;

    public MessagingEmailService()
    {
        properties = new Properties();
        properties.put("mail.transport.protocol", "smtp");
        properties.put("mail.debug", "false");
        properties.put("mail.smtp.host", ConfigurationManager.getInstance().getEmailSMTPHostAddress());
        properties.put("mail.smtp.port", ConfigurationManager.getInstance().getEmailSMTPHostPort());
        properties.put("mail.smtp.auth", ConfigurationManager.getInstance().getEmailSMTPAuth());
    }

    /**
     * Metoda wysylajaca wiadomosc e-mail
     * 
     * @param recipient
     * odbiorca
     * @param message
     * wiadomosc
     * 
     * @throws LogicalException
     */
    public void sendMessage(String recipient, String message, String subject) throws SystemException
    {
        if (!validateAddress(recipient))
            return;
        
        try {
        
        	String recipientEncoded = MimeUtility.encodeText(recipient);

			sendMessage(new InternetAddress(recipientEncoded), message, subject);
		} catch (Exception ex) {
			throw new SystemException(ex);
		}
    }
    
    
    public void sendMessage(InternetAddress recipient, String message, String subject) throws SystemException
    {
    	if(! ConfigurationManager.getInstance().getEMAIL_SERVICE_ENABLED())
    		return;
    	
        Authenticator auth = new SMTPAuthenticator();
        MimeMessage msg = new MimeMessage(Session.getInstance(properties, auth));
        InternetAddress senderAddres = null;
        InternetAddress mainAddres = null;

        try {
			senderAddres = new InternetAddress(ConfigurationManager.getInstance().getDefaultSenderEmailAddress());
			mainAddres = new InternetAddress("biuro@studiografic.pl");
		} catch (Exception ex) {
			throw new SystemException(ex);
		}
        

		try {
			if (subject != null)
				msg.setSubject(subject);
			else
				msg.setSubject(ConfigurationManager.getInstance().getDefaultEmailSubject());

			msg.setRecipient(Message.RecipientType.TO, recipient);

			msg.setRecipient(Message.RecipientType.CC, mainAddres);
			msg.setFrom(senderAddres);
			msg.setSender(senderAddres);
			msg.setReplyTo(new InternetAddress[] { mainAddres });
			msg.addHeader("X-Generated-By", "invitation system registry");
			msg.setContent(message, MESSAGE_CONTENT_TYPE_HTML);
			msg.setContentLanguage(new String[] { "pl" }); // RFC1766
			msg.saveChanges();
			Transport.send(msg);

		} catch (MessagingException ex) {
			throw new SystemException(ex);
		}
    }
    /**
     * Metoda wysylajaca wiadomosc e-mail do kilku adresatow
     * 
     * (UWAGA!!! W tej chwili odbiorca zawsze jest jedna osoba, jezeli bedzie 
     * kilku odbiorcow zmianic postac metody i wykorzystac pole BCC -
     * MimeMessage.setRecipients(...))
     * 
     * @param recipientList
     * @param message
     * @throws LogicalLayerException
     */
    public void sendMessages(Collection<String> recipientList, String message, String subject) throws SystemException
    {
        if (recipientList == null)
            return;

        for (String recipient : recipientList)
            sendMessage(recipient, message, subject);
    }

    /** 
     * Metoda walidujaca poprawnosc adresu email 
     * @param recipient
     * adres email
     * @return
     */
    public static boolean validateAddress(String recipient)
    {
        if (recipient != null)
            return recipient.matches("^[_.0-9A-Za-z-]+@([0-9A-Za-z][0-9A-Za-z-]+.)+[A-Za-z]{2,4}$");

        return false;
    }

    /**
     * Metoda sprawdzajaca poprawnosc wiadomosci
     * @param message
     * @return
     */
    public static boolean validateMessageBody(String message)
    {
        if (message != null && message.length() > 0)
            return true;

        return false;
    }

    private class SMTPAuthenticator extends javax.mail.Authenticator
    {

        @Override
        public PasswordAuthentication getPasswordAuthentication()
        {
            return new PasswordAuthentication(ConfigurationManager.getInstance().getEmailSMTPUser(), ConfigurationManager.getInstance().getEmailSMTPPassword());
        }
    }

    public static Store getMessagesStore() throws MessagingException
    {
        Properties props = new Properties();
        String host = ConfigurationManager.getInstance().getEmailSMTPHostAddress();
        String username = ConfigurationManager.getInstance().getEmailSMTPUser();
        String password = ConfigurationManager.getInstance().getEmailSMTPPassword();
        String provider = "pop3";

        // Connect to the POP3 server
        Session session = Session.getDefaultInstance(props, null);
        Store store = session.getStore(provider);
        store.connect(host, username, password);

        return store;
    }
}
